package com.study.thread;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;

/**
 * @Description: 使用 lockInterruptibly 处理可中断的等待
 * @Author King
 * @Date 2024/12/15 12:38
 */


public class InterruptibleDownloader {
    private static final Log log = LogFactory.getLog(InterruptibleDownloader.class.getName());

    static ReentrantLock lock = new ReentrantLock();

    public static void main(String[] args) throws InterruptedException {
        //主线程main执行，创建线程t2
        Thread t2 = new Thread(() -> {
            try {
                lock.lock();
                log.info("---------t2线程获取锁,然后去睡5秒---------");
                TimeUnit.SECONDS.sleep(5);
                log.info("---------t2线程睡5秒后醒来了---------");
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }, "t2");
        t2.start();

        //主线程main睡2秒，然后创建线程t1
        TimeUnit.SECONDS.sleep(2); //此处主线程睡眠主要为了确保t2先拿到锁，实现效果

        //创建线程t1
        Thread t1 = new Thread(() -> {
            try {
//                System.out.println("t1 运行中：" + Thread.currentThread().getState());
                lock.lock();//(此处t1尝试加锁失败，睡眠，因为等待上面的t2线程释放锁)
                log.info("---------t1获取到锁---------");
            } catch (Exception e) {
//                System.out.println("t1 catch中：" + Thread.currentThread().getState());
                log.info("---------t1 catch 被主线程打断了，没有获取到锁---------");
                e.printStackTrace();
            } finally {
                lock.unlock();
            }
        }, "t1");
        t1.start();

//        new Thread(() -> {
//            LocalTime sixSecondsLater = LocalTime.now().plusSeconds(4);
//            while (true) {
//                log.info("t1 getState().name() = " + t1.getState().name());
////                log.info("t2 getState().name() = " + t2.getState().name());
//                if (LocalTime.now().isAfter(sixSecondsLater)) {
//                    break;
//                }
//            }
//
//        }).start();

        TimeUnit.SECONDS.sleep(1);
        //主线程睡完2秒后醒来，打断t1
        log.info("---------主线程睡完2秒后醒来，打断t1---------");
        System.out.println("打断前 " + t1.getState());
        t1.interrupt();//打断t1,所以t1不再等待t2释放锁了
        System.out.println("打断后 " + t1.getState());

        /*
        打断 lock.lock()，t1没有异常，且不会释放锁，继续执行了
        2024-12-15 17:22:12 [t2] INFO  c.s.thread.InterruptibleDownloader - ---------t2线程获取锁,然后去睡5秒---------
        2024-12-15 17:22:14 [main] INFO  c.s.thread.InterruptibleDownloader - ---------主线程睡完2秒后醒来，打断t1---------
        2024-12-15 17:22:17 [t2] INFO  c.s.thread.InterruptibleDownloader - ---------t2线程睡5秒后醒来了---------
        2024-12-15 17:22:17 [t1] INFO  c.s.thread.InterruptibleDownloader - ---------t1获取到锁---------
         */

        /*
        RUNNABLE
        WAITING
        打断后：RUNNABLE
        TERMINATED
        */
    }
}

